﻿/*****************************************************************//**
 * @file    FITKAcousticsVTKGraphObjectModel.h
 * @brief   Shape graph object 3D model for VTK graph widget.

 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-10-28
 *********************************************************************/

#ifndef __FITKFACOUSTICSVTKGRAPHOBJECTMODEL_H__
#define __FITKFACOUSTICSVTKGRAPHOBJECTMODEL_H__

#include "FITKAcousticsVTKGraphObject3D.h"

#include <QVector>
#include <QVariant>

// Forward declaration
class vtkPolyData;
class vtkUnstructuredGrid;
class vtkDataSet;
class vtkDoubleArray;
class vtkCubeSource;
class vtkGlyph3D;
class vtkIntArray;

class FITKAcousticsVTKGraphActor;

namespace Interface
{
    class FITKAbsGeoCommand;
    class FITKGeometryMeshVS;
    class FITKVirtualTopoManager;
    class FITKAbsVirtualTopo;
}

namespace Exchange
{
    class FITKAcousticsVTKColorMap;
    class FITKAcousticsVTKGraphObjectSelect;
}

namespace Exchange
{
    /**
     * @brief   Shape graph object 3D model for VTK graph widget.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-06-05
     */
    class FITKACOUSTICSGRAPHADAPTORAPI FITKAcousticsVTKGraphObjectModel : public FITKAcousticsVTKGraphObject3D
    {
        // Regist
        FITKGraphObjectRegist(FITKAcousticsVTKGraphObjectModel, FITKAcousticsVTKGraphObject3D);
        FITKCLASS(Exchange, FITKAcousticsVTKGraphObjectModel);

    public:
        /**
         * @brief   Constructor.
         * @param   modelData: The shape model data object need to exchange
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        FITKAcousticsVTKGraphObjectModel(Interface::FITKAbsGeoCommand* modelData);

        /**
         * @brief   Destructor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        ~FITKAcousticsVTKGraphObjectModel();

        /**
         * @brief   Update all graph actors.[override]
         * @param   forceUpdate: Force update[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-24
         */
        void update(bool forceUpdate = false) override;
        /**
         * @brief    获取数据可见性
         * @return   bool                   是否可见
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-26
         */
        bool getDataVisibility() override;

        /**
         * @brief   Update the visibility with data object's visibility.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-12
         */
        void updateVisibility() override;

        /**
         * @brief   Show or hide graph object.[override]
         * @param   visibility: The visibility of graph object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-14
         */
        void setVisible(bool visibility) override;

        /**
         * @brief   Set the visibility of the vertice.
         * @param   visibility: The visibility of vertice actor
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        void setVerticesVisible(bool visibility);

        /**
         * @brief   Set the visibility of the edges and wires.
         * @param   visibility: The visibility of vertice actor
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        void setEdgesVisible(bool visibility);

        /**
         * @brief   Set the visibility of the faces and shells.
         * @param   visibility: The visibility of vertice actor
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        void setFacesVisible(bool visibility);

        /**
         * @brief   Set the visibility of the solids.
         * @param   visibility: The visibility of vertice actor
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        void setSolidsVisible(bool visibility);

        /**
         * @brief   Set the color for single edge, face or solid.[override]
         * @param   color: The color
         * @param   type: The shape mesh type
         * @param   index: The shape id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-11
         */
        void setColor(QColor color, FITKAcousticsVTKCommons::ShapeType type, int index) override;

        /**
         * @brief    高亮渲染对象
         * @param[i] hightObjID                     高亮数据id【仅复合数据使用】
         * @param[i] type                           需要突出显示形状类型
         * @param[i] color                          高亮颜色
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-05
         */
        void highlight(int hightObjID = -1, FITKAcousticsVTKCommons::ShapeType type = FITKAcousticsVTKCommons::ShapeTypeNone, QColor color = QColor()) override;
        /**
         * @brief    取消高亮渲染对象
         * @param[i] hightObjID                     取消高亮数据id【仅复合数据使用】
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-05
         */
        void disHighlight(int hightObjID = -1) override;

        /**
         * @brief   Advanced highlight mode for highlighting part of the graph actors.[override]
         * @param   type: The type of the model need to be highlighted
         * @param   indice: The given indice of the model component need to be highlight
         * @param   color: The given color for highlighting this time[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-23
         */
        void advanceHighlight(FITKAcousticsVTKCommons::ShapeType type, QVector<int> indice, QColor color = QColor()) override;

        /**
         * @brief   Dis-highlight the graph actors if the graph object is in advanced highlighting mode.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-23
         */
        void disAdvanceHighlight() override;

        /**
         * @brief   Get the number of components of the given type.[override]
         * @param   type: The shape type
         * @return  The count
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-22
         */
        int getNumberOf(FITKAcousticsVTKCommons::ShapeType type) override;

        // For picking.
        //@{
        /**
         * @brief   Set if the graph object pickable mode.[override]
         * @param   mode: The pickable mode
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        void setPickMode(FITKAcousticsVTKCommons::ShapePickMode mode) override;

        /**
         * @brief   Get the shape id by the given shape type and VTK cell id.[override]
         * @param   vtkId: The VTK point or cell id in shape data
         * @param   topAbsShapeType: The shape type of the given ID( the same as TopAbs_ShapeEnum )
         * @return  The shape id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-19
         */
        int getShapeIdByVTKCellId(int vtkId, FITKAcousticsVTKCommons::ShapeMeshAbsEnum topAbsShapeType) override;

        /**
         * @brief   Get the VTK point or cell indice by the given shape type and shape id.[override]
         * @param   shapeId: The shape id in shape data
         * @param   topAbsShapeType: The shape type of the given ID( the same as TopAbs_ShapeEnum )
         * @return  The cell indice[const]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        const QVector<int> getVTKCellIdsByShapeId(int shapeId, FITKAcousticsVTKCommons::ShapeMeshAbsEnum topAbsShapeType) override;

        /**
         * @brief   Get the VTK cell indice by the given shape type and cell id in VTK.[override]
         * @param   cellId: The cell id in VTK
         * @param   topAbsShapeType: The shape type of the given ID( the same as TopAbs_ShapeEnum )
         * @return  The cell indice[const]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        const QVector<int> getVTKCellIdsByVTKCellId(int cellId, FITKAcousticsVTKCommons::ShapeMeshAbsEnum topAbsShapeType) override;
        /**
         * @brief    通过几何形状id获取虚拓扑索引
         * @param[i] shapeId                                 几何形状id（几何虚拓扑id）
         * @param[i] topAbsShapeType                         几何形状类型
         * @return   int                                     虚拓扑索引
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-12
         */
        int getVirTopoIndexByShapeId(int shapeId, FITKAcousticsVTKCommons::ShapeMeshAbsEnum topAbsShapeType) override;
        //@}

        // For highlighting.
        //@{
        /**
         * @brief   Get the VTK mesh grid by the given mesh type.[override]
         * @param   type: The shape's VTK mesh type
         * @return  The vtkDataSet object of the given type of mesh
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        vtkDataSet* getMesh(FITKAcousticsVTKCommons::ShapeType type) override;
        //@}

        // Test function
        //@{
        /**
         * @brief   Test function.[override]
         * @param   details: The input information
         * @return  Is success
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        bool test(QVariant& details) override;
        //@}

    private:
        /**
         * @brief   Initialize.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        void init();

        /**
         * @brief   Convert the trianglation data to a vtkDataSet.
         * @return  Is valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-12
         */
        bool meshVSToVtkDataSet();

        // Split shape data and save the id map.
        //@{
        /**
         * @brief    创建点的网格数据
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-18
         */
        void createVertexGrid();
        /**
         * @brief    创建线的网格数据
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-18
         */
        void createEdgeGrid();
        /**
         * @brief    创建面的网格数据
         * @return   void
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-18
         */
        void createFaceGrid();
        /**
         * @brief    创建体的网格数据
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-18
         */
        void createSolidGrid();

        /**
         * @brief   Internal function, add the normals to the grid data.
         * @param   polyData: The poly data
         * @param   normals: The normal data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        void addPointNormals(vtkPolyData* polyData, vtkDoubleArray* normals);
        //@}

        /**
         * @brief   Generate the data set by the shape data.
         * @return  Is OK
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-24
         */
        bool generateDataSet();

        /**
         * @brief   Generate the shape with the vtkDataSet.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        void generateGraph();

        /**
         * @brief   Clear all data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-24
         */
        void clearData();

        /**
         * @brief   Internal function - Add the given virtual topo's edges to the given grid.
         * @param   vTopo: The virtual topo
         * @param   ugrid: The edges grid data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        void addEdges(Interface::FITKAbsVirtualTopo* vTopo, vtkUnstructuredGrid* ugrid);
        /**
         * @brief    更新点的大小
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-10
         */
        void updateSizeByPoints();
        /**
         * @brief    更新颜色
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-11
         */
        void updateColor();
        /**
         * @brief    更新点ID列表
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-02-11
         */
        void updatePointIDVector();
    private:
        /**
         * @brief  图形大小
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-10
         */
        double m_glyphSize = 30;
        /**
         * @brief   The shape data of the model.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-12
         */
        Interface::FITKGeometryMeshVS* m_triData{ nullptr };

        /**
         * @brief   The topo manager of the shape agent.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-13
         */
        Interface::FITKVirtualTopoManager* m_topoMgr{ nullptr };

        // For colors.
        //@{
        /**
         * @brief   The color map key words for showing default model color.[const]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-11
         */
        const QString c_defaultArrName = "Default";

        /**
         * @brief  几何点高亮提取器
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-19
         */
        FITKAcousticsVTKGraphObjectSelect* m_highlightSelectorVer = nullptr;
        /**
         * @brief  几何线高亮提取器
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-19
         */
        FITKAcousticsVTKGraphObjectSelect* m_highlightSelectorEdge = nullptr;
        /**
         * @brief  几何面高亮提取器
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-19
         */
        FITKAcousticsVTKGraphObjectSelect* m_highlightSelectorFace = nullptr;
        /**
         * @brief  几何体高亮提取器
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-19
         */
        FITKAcousticsVTKGraphObjectSelect* m_highlightSelectorSolid = nullptr;

        /**
         * @brief   The color map for vertex data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-11
         */
        FITKAcousticsVTKColorMap* m_colorMapVertex{ nullptr };

        /**
         * @brief   The color map for edge data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-11
         */
        FITKAcousticsVTKColorMap* m_colorMapEdge{ nullptr };

        /**
         * @brief   The color map for face data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-11
         */
        FITKAcousticsVTKColorMap* m_colorMapFace{ nullptr };

        /**
         * @brief   The color map for solid data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        FITKAcousticsVTKColorMap* m_colorMapSolid{ nullptr };
        //@}

        /**
         * @brief   The model vertice grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        vtkUnstructuredGrid* m_gridVertex{ nullptr };

        /**
         * @brief   The model edges grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        vtkUnstructuredGrid* m_gridEdge{ nullptr };

        /**
         * @brief   The model faces grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        vtkPolyData* m_gridFace{ nullptr };

        /**
         * @brief   The model solids grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        vtkPolyData* m_gridSolid{ nullptr };

        /**
         * @brief   The normals for the face points.( For better visualization. )
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-01
         */
        vtkDoubleArray* m_normalFacePoint{ nullptr };

        /**
         * @brief   The normals for the solid points.( For better visualization. )
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        vtkDoubleArray* m_normalSolidPoint{ nullptr };

        /**
         * @brief   The model actor for vertice.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        FITKAcousticsVTKGraphActor* m_fActorVertex{ nullptr };

        /**
         * @brief   The model actor for edges.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        FITKAcousticsVTKGraphActor* m_fActorEdge{ nullptr };

        /**
         * @brief   The model actor for faces.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-05
         */
        FITKAcousticsVTKGraphActor* m_fActorFace{ nullptr };

        /**
         * @brief   The model actor for solids.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        FITKAcousticsVTKGraphActor* m_fActorSolid{ nullptr };

        // Additional actors.
        //@{
        /**
         * @brief   The model faces' edges grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        vtkUnstructuredGrid* m_gridFaceEdges{ nullptr };

        /**
         * @brief   The model solids' edges grid data for VTK.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        vtkUnstructuredGrid* m_gridSolidEdges{ nullptr };
        /**
         * @brief  点数据源
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-10
         */
        vtkCubeSource* m_cubeSource = nullptr;
        /**
         * @brief  图形过滤器
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-10
         */
        vtkGlyph3D* m_glyph3D = nullptr;
        /**
         * @brief  几何点ID存储数组
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-11
         */
        vtkIntArray* m_nodeIdArray = nullptr;
        /**
         * @brief  点ID在数值中的标记
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-11
         */
        QString m_nodeIdArrayName = "__node_id__";
        //@}

        // For picking.
        //@{
        // VTK -> Shape
        //@{
        /**
         * @brief   The id array for getting the edge id of picked cell.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        QVector<int> m_cellIdEdgeIdMap;

        /**
         * @brief   The id array for getting the face id of picked cell.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        QVector<int> m_cellIdFaceIdMap;

        /**
         * @brief   The id array for getting the face id of picked cell.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        QVector<int> m_cellIdSolidIdMap;
        //@}

        // Shape -> VTK
        //@{
        /**
         * @brief   The id array for getting the cell id with edge id.
         *          The key is the shape id of virtual topo,
         *          the values are the VTK cell id in vtkDataSet.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        QHash<int, int> m_edgeIdCellIdMap;
        //@}

        /**
         * @brief  几何点虚拓扑id与虚拓扑索引映射关系
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-12
         */
        QHash<int, int> m_pointVirtualTopIdVirtualIndex = {};
        /**
         * @brief  几何线虚拓扑id与虚拓扑索引映射关系
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-12
         */
        QHash<int, int> m_edgeVirtualTopIdVirtualIndex = {};
        /**
         * @brief  几何面虚拓扑id与虚拓扑索引映射关系
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-12
         */
        QHash<int, int> m_faceVirtualTopIdVirtualIndex = {};
        /**
         * @brief  几何体虚拓扑id与虚拓扑索引映射关系
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-12
         */
        QHash<int, int> m_solidVirtualTopIdVirtualIndex = {};
        /**
         * @brief  点ID与立方体单元id映射
         *         <点ID ,<立方体单元id>>
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-02-11
         */
        QHash<int, QVector<int>> m_pointIdCellIdsHash = {};
        /**
         * @brief   The solid and face id map.
         *          The key is the shape id of virtual topo,
         *          the values are the VTK cell ids in vtkDataSet.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-06-06
         */
        QHash<int, QVector<int>> m_faceIdCellIdsHash;

        /**
         * @brief   The solid and face id map.
         *          The key is the shape id of virtual topo,
         *          the values are the VTK cell ids in vtkDataSet.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        QHash<int, QVector<int>> m_solidIdCellIdsHash;
        //@}
        //@}

        /**
         * @brief   The visibility of the vertice.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        bool m_showVert = true;

        /**
         * @brief   The visibility of the edges and wires.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        bool m_showEdge = true;

        /**
         * @brief   The visibility of the faces and shells.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        bool m_showFace = true;

        /**
         * @brief   The visibility of the solids.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-10-31
         */
        bool m_showSolid = true;

        /**
         * @brief   The shape state tag.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-19
         */
        QVariant m_shapeState;

    };
}   // namespace Exchange

#endif // __FITKFACOUSTICSVTKGRAPHOBJECTMODEL_H__
